home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 011 / assywind.arc / WINDO.INC next >
Text File  |  1986-07-03  |  27KB  |  500 lines

  1. { ===================================================================== }
  2. {  WINDO - Windowing routines for Turbo PASCAL                          }
  3. {                                                                       }
  4. {     Author:   Michael Burton                                          }
  5. {               15540 Boot Hill Rd.                                     }
  6. {               Hayden Lake, ID 83835                                   }
  7. {               (208) 772-9347 (after 1800 PST)                         }
  8. {     Revision: 2.2                                                     }
  9. {     Date:     02 July 1986                                            }
  10. {                                                                       }
  11. {  Execute the WINTUTOR program for an explanation of use.              }
  12. {                                                                       }
  13. {  This is a 'Shareware' program.  If you find it to be of significant  }
  14. {  use to you, a $10 donation to the above address would be greatly     }
  15. {  appreciated.  This would also place you on our mailing list to keep  }
  16. {  you informed of upgrades to Windo and of new programs.               }
  17. {                                                                       }
  18. { Modifications:                                                        }
  19. { DATE      Rev  Description                                            }
  20. { 04 Mar 86 2.1  Make the heap available check properly                 }
  21. { 02 Jul 86 2.2  Get proper string length in GETDISP and DISPALL        }
  22. { 03 Jul 86 2.3  Change Set_Cursor to properly handle monochrome        }
  23. { ===================================================================== }
  24. type
  25.      windimtype = record
  26.                      colb,rowb,cole,rowe,attrib,bordr,lastx,lasty : byte;
  27.                   end;
  28.      charptr = ^char;
  29.      winstr = string[80];
  30.      brdtype = record
  31.                   ul,ur,ll,lr,hz,vtl,vtr: char;
  32.                end;
  33.  
  34. const maxwin  = 30;        { Total number of windows on screen at any time }
  35.       noneb   = 0;         { No border           }
  36.       singleb = 1;         { Single border       }
  37.       doubleb = 2;         { Double border       }
  38.       mixedb  = 3;         { Mixed border        }
  39.       solidb  = 4;         { Solid border        }
  40.       dimondb = 5;         { Diamond border      }
  41.       circleb = 6;         { Circles border      }
  42.       lhatchb = 7;         { light hatch border  }
  43.       mhatchb = 8;         { medium hatch border }
  44.       dhatchb = 9;         { dense hatch border  }
  45.       brd: array[1..9] of brdtype =  (
  46.           (ul:'┌';ur:'┐';ll:'└';lr:'┘';hz:'─';vtl:'│';vtr:'│'),  { single }
  47.           (ul:'╔';ur:'╗';ll:'╚';lr:'╝';hz:'═';vtl:'║';vtr:'║'),  { double }
  48.           (ul:'╒';ur:'╕';ll:'╘';lr:'╛';hz:'═';vtl:'│';vtr:'│'),  { mixed  }
  49.           (ul:'█';ur:'█';ll:'█';lr:'█';hz:'█';vtl:'▌';vtr:'▐'),  { solid  }
  50.           (ul:' ';ur:' ';ll:' ';lr:' ';hz:' ';vtl:' ';vtr:' '),  { diamond}
  51.           (ul:' ';ur:' ';ll:' ';lr:' ';hz:' ';vtl:' ';vtr:' '),  { circle }
  52.           (ul:'░';ur:'░';ll:'░';lr:'░';hz:'░';vtl:'░';vtr:'░'),  { lhatch }
  53.           (ul:'▒';ur:'▒';ll:'▒';lr:'▒';hz:'▒';vtl:'▒';vtr:'▒'),  { mhatch }
  54.           (ul:'▓';ur:'▓';ll:'▓';lr:'▓';hz:'▓';vtl:'▓';vtr:'▓')); { dhatch }
  55.  
  56. var
  57.      wndo    : Array [0..maxwin] of windimtype; { window attributes      }
  58.      wndoptr : Array [1..maxwin] of charptr; { pointer to window on heap }
  59.      tmpptr  : charptr;                      { temporary pointer         }
  60.      l_i  : byte;                            { level index               }
  61.      wndostr : winstr;                       { string for building wndos }
  62.  
  63. { ===================================================================== }
  64. { GETDISP - Get an array of characters from the CRT display and store   }
  65. {           them in tostrng.                                            }
  66. {           The row and column inputs are relative to zero and are      }
  67. {           also relative to the entire screen, not any open window.    }
  68. {                                                                       }
  69. {    Inputs:                                                            }
  70. {       colb      : byte;    Starting column (0 - 79)                   }
  71. {       rowb      : byte;    Starting row    (0 - 24)                   }
  72. {       len       : byte;    length of array                            }
  73. {       tostrng   : charptr; Pointer to character storage               }
  74. { ===================================================================== }
  75. Procedure GetDisp(colb,rowb,len : byte; tostrng : charptr);
  76. Begin
  77.    Inline(
  78.       $1E/                    {           PUSH   DS               }
  79.       $8A/$86/rowb/           {           MOV    AL,rowb[BP]      }
  80.       $B3/$50/                {           MOV    BL,80            }
  81.       $F6/$E3/                {           MUL    BL               }
  82.       $2B/$DB/                {           SUB    BX,BX            }
  83.       $8A/$9E/colb/           {           MOV    BL,colb[BP]      }
  84.       $03/$C3/                {           ADD    AX,BX            }
  85.       $03/$C0/                {           ADD    AX,AX            }
  86.       $8B/$F8/                {           MOV    DI,AX            }
  87.       $C4/$B6/tostrng/        {           LES    SI,tostrng[BP]   }
  88.       $8B/$8E/len/            {           MOV    CX,len[BP]       }
  89.       $03/$C9/                {           ADD    CX,CX            }
  90.       $2B/$C0/                {           ADD    AX,AX            }
  91.       $8E/$D8/                {           MOV    DS,AX            }
  92.       $A0/$49/$04/            {           MOV    AL,DS:[0449H]    }
  93.       $22/$C9/                {           AND    CL,CL            }
  94.       $74/$32/                {           JZ     DONE             }
  95.       $2C/$07/                {           SUB    AL,7             }
  96.       $74/$20/                {           JZ     MONO             }
  97.       $BA/$00/$B8/            {           MOV    DX,0B800H        }
  98.       $8E/$DA/                {           MOV    DS,DX            }
  99.       $BA/$DA/$03/            {           MOV    DX,03DAH         }
  100.       $EC/                    { TESTLOW:  IN     AL,DX            }
  101.       $A8/$01/                {           TEST   AL,1             }
  102.       $75/$FB/                {           JNZ    TESTLOW          }
  103.       $FA/                    {           CLI                     }
  104.       $EC/                    { TESTHI:   IN     AL,DX            }
  105.       $A8/$01/                {           TEST   AL,1             }
  106.       $74/$FB/                {           JZ     TESTHI           }
  107.       $8A/$1D/                {           MOV    BL,DS:[DI]       }
  108.       $26/$88/$1C/            {           MOV    ES:[SI],BL       }
  109.       $47/                    {           INC    DI               }
  110.       $46/                    {           INC    SI               }
  111.       $E2/$EC/                {           LOOP   GETCHAR          }
  112.       $2A/$C0/                {           SUB    AL,AL            }
  113.       $74/$0E/                {           JZ     DONE             }
  114.       $BA/$00/$B0/            { MONO:     MOV    DX,0B000H        }
  115.       $8E/$DA/                {           MOV    DS,DX            }
  116.       $8A/$1D/                { MONO1:    MOV    BL,DS:[DI]       }
  117.       $26/$88/$1C/            {           MOV    ES:[SI],BL       }
  118.       $47/                    {           INC    DI               }
  119.       $46/                    {           INC    SI               }
  120.       $E2/$F7/                {           LOOP   MONO1            }
  121.       $1F);                   { DONE:     POP    DS               }
  122. End;
  123.  
  124. { ===================================================================== }
  125. { DISPALL - Display an array of characters and attributes on the CRT.   }
  126. {           The array is usually one that has been created using the    }
  127. {           GetDisp procedure.                                          }
  128. {           The row and column inputs are relative to zero and are      }
  129. {           also relative to the entire screen, not any open window.    }
  130. {                                                                       }
  131. {    Inputs:                                                            }
  132. {       colb      : byte;    Starting column  (0 - 79)                  }
  133. {       rowb      : byte;    Starting row     (0 - 24)                  }
  134. {       len       : byte;    length of array  (not including attributes)}
  135. {       fromstrng : charptr; Pointer to array to display                }
  136. { ===================================================================== }
  137. Procedure DispAll(colb,rowb,len : byte; fromstrng : charptr);
  138. Begin
  139.    Inline(
  140.       $1E/                    {           PUSH   DS               }
  141.       $8A/$86/rowb/           {           MOV    AL,rowb[BP]      }
  142.       $B3/$50/                {           MOV    BL,80            }
  143.       $F6/$E3/                {           MUL    BL               }
  144.       $2B/$DB/                {           SUB    BX,BX            }
  145.       $8A/$9E/colb/           {           MOV    BL,colb[BP]      }
  146.       $03/$C3/                {           ADD    AX,BX            }
  147.       $03/$C0/                {           ADD    AX,AX            }
  148.       $8B/$F8/                {           MOV    DI,AX            }
  149.       $C4/$B6/fromstrng/      {           LES    SI,fromstrng[BP] }
  150.       $8B/$8E/len/            {           MOV    CX,len[BP]       }
  151.       $03/$C9/                {           ADD    CX,CX            }
  152.       $2B/$C0/                {           ADD    AX,AX            }
  153.       $8E/$D8/                {           MOV    DS,AX            }
  154.       $A0/$49/$04/            {           MOV    AL,DS:[0449H]    }
  155.       $22/$C9/                {           AND    CL,CL            }
  156.       $74/$32/                {           JZ     DONE             }
  157.       $2C/$07/                {           SUB    AL,7             }
  158.       $74/$20/                {           JZ     MONO             }
  159.       $BA/$00/$B8/            {           MOV    DX,0B800H        }
  160.       $8E/$DA/                {           MOV    DS,DX            }
  161.       $BA/$DA/$03/            {           MOV    DX,03DAH         }
  162.       $26/$8A/$1C/            { GETCHAR:  MOV    BL,ES:[SI]       }
  163.       $EC/                    { TESTLOW:  IN     AL,DX            }
  164.       $A8/$01/                {           TEST   AL,1             }
  165.       $75/$FB/                {           JNZ    TESTLOW          }
  166.       $FA/                    {           CLI                     }
  167.       $EC/                    { TESTHI:   IN     AL,DX            }
  168.       $A8/$01/                {           TEST   AL,1             }
  169.       $74/$FB/                {           JZ     TESTHI           }
  170.       $88/$1D/                {           MOV    DS:[DI],BL       }
  171.       $47/                    {           INC    DI               }
  172.       $46/                    {           INC    SI               }
  173.       $E2/$EC/                {           LOOP   GETCHAR          }
  174.       $2A/$C0/                {           SUB    AL,AL            }
  175.       $74/$0E/                {           JZ     DONE             }
  176.       $BA/$00/$B0/            { MONO:     MOV    DX,0B000H        }
  177.       $8E/$DA/                {           MOV    DS,DX            }
  178.       $26/$8A/$1C/            { MONO1:    MOV    BL,ES:[SI]       }
  179.       $88/$1D/                {           MOV    DS:[DI],BL       }
  180.       $47/                    {           INC    DI               }
  181.       $46/                    {           INC    SI               }
  182.       $E2/$F7/                {           LOOP   MONO1            }
  183.       $1F);                   { DONE:     POP    DS               }
  184. End;
  185.  
  186. { ===================================================================== }
  187. { DISPLINE - Display a string of characters on the CRT (with the same   }
  188. {            attributes)                                                }
  189. {           The row and column inputs are relative to zero and are      }
  190. {           also relative to the entire screen, not any open window.    }
  191. {                                                                       }
  192. {    Inputs:                                                            }
  193. {       colb      : byte;       Starting column  (0 - 79)               }
  194. {       rowb      : byte;       Starting row     (0 - 24)               }
  195. {       attrib    : byte;       Line attributes                         }
  196. {       fromstrng : string[80]; String to display                       }
  197. { ===================================================================== }
  198. Procedure DispLine(colb,rowb,attrib : byte; VAR fromstrng : winstr);
  199. Begin
  200.    Inline(
  201.       $1E/                    {           PUSH   DS               }
  202.       $8A/$86/rowb/           {           MOV    AL,rowb[BP]      }
  203.       $B3/$50/                {           MOV    BL,80            }
  204.       $F6/$E3/                {           MUL    BL               }
  205.       $2B/$DB/                {           SUB    BX,BX            }
  206.       $8A/$9E/colb/           {           MOV    BL,colb[BP]      }
  207.       $03/$C3/                {           ADD    AX,BX            }
  208.       $03/$C0/                {           ADD    AX,AX            }
  209.       $8B/$F8/                {           MOV    DI,AX            }
  210.       $8A/$BE/attrib/         {           MOV    BH,attrib[BP]    }
  211.       $C4/$B6/fromstrng/      {           LES    SI,fromstrng[BP] }
  212.       $2B/$C9/                {           SUB    CX,CX            }
  213.       $26/$8A/$0C/            {           MOV    CL,ES:[SI]       }
  214.       $2B/$C0/                {           ADD    AX,AX            }
  215.       $8E/$D8/                {           MOV    DS,AX            }
  216.       $A0/$49/$04/            {           MOV    AL,DS:[0449H]    }
  217.       $22/$C9/                {           AND    CL,CL            }
  218.       $74/$34/                {           JZ     DONE             }
  219.       $2C/$07/                {           SUB    AL,7             }
  220.       $74/$21/                {           JZ     MONO             }
  221.       $BA/$00/$B8/            {           MOV    DX,0B800H        }
  222.       $8E/$DA/                {           MOV    DS,DX            }
  223.       $BA/$DA/$03/            {           MOV    DX,03DAH         }
  224.       $46/                    { GETCHAR:  INC    SI               }
  225.       $26/$8A/$1C/            {           MOV    BL,ES:[SI]       }
  226.       $EC/                    { TESTLOW:  IN     AL,DX            }
  227.       $A8/$01/                {           TEST   AL,1             }
  228.       $75/$FB/                {           JNZ    TESTLOW          }
  229.       $FA/                    {           CLI                     }
  230.       $EC/                    { TESTHI:   IN     AL,DX            }
  231.       $A8/$01/                {           TEST   AL,1             }
  232.       $74/$FB/                {           JZ     TESTHI           }
  233.       $89/$1D/                {           MOV    DS:[DI],BX       }
  234.       $47/                    {           INC    DI               }
  235.       $47/                    {           INC    DI               }
  236.       $E2/$EB/                {           LOOP   GETCHAR          }
  237.       $2A/$C0/                {           SUB    AL,AL            }
  238.       $74/$0F/                {           JZ     DONE             }
  239.       $BA/$00/$B0/            { MONO:     MOV    DX,0B000H        }
  240.       $8E/$DA/                {           MOV    DS,DX            }
  241.       $46/                    { MONO1:    INC    SI               }
  242.       $26/$8A/$1C/            {           MOV    BL,ES:[SI]       }
  243.       $89/$1D/                {           MOV    DS:[DI],BX       }
  244.       $47/                    {           INC    DI               }
  245.       $47/                    {           INC    DI               }
  246.       $E2/$F6/                {           LOOP   MONO1            }
  247.       $1F);                   { DONE:     POP    DS               }
  248. End;
  249.  
  250. { ======================================================================== }
  251. { NAME: Normalize                   VERSION: 1.0   DATE: 23 January 1986   }
  252. { AUTHOR: Michael Burton                                                   }
  253. { DESCRIPTION: Normalize coordinates                                       }
  254. { INPUTS: s,e : byte;  start and end coordinates                           }
  255. { OUTPUTS: s,e : byte; coordinates with s < e                              }
  256. {                                                                          }
  257. { ======================================================================== }
  258. Procedure Normalize(VAR s,e: byte);
  259. Var temp: byte;
  260. Begin
  261.    If s > e Then
  262.    Begin
  263.       temp := s;
  264.       s    := e;
  265.       e    := temp;
  266.    End;
  267. End;
  268.  
  269. { ======================================================================== }
  270. { NAME: Bleep                       VERSION: 1.0   DATE: 14 January 1986   }
  271. { AUTHOR: Michael Burton                                                   }
  272. { DESCRIPTION: Produce a bleeping sound times number of times              }
  273. { INPUTS: times : byte;  The number of bleeps required                     }
  274. {                                                                          }
  275. { ======================================================================== }
  276. Procedure Bleep(times : byte);
  277. Var i : byte;
  278. Begin
  279.    For i := 1 To times Do
  280.    Begin
  281.       Nosound;
  282.       Sound(880);
  283.       Delay(60);
  284.       Sound(440);
  285.       Delay(60);
  286.       Nosound;
  287.    End;
  288. End;
  289.  
  290. { ======================================================================== }
  291. { NAME: Set_Cursor                  VERSION: 1.0   DATE: 27 January 1986   }
  292. { AUTHOR:                                                                  }
  293. { DESCRIPTION: Set the cursor size                                         }
  294. { INPUTS: The number of cursor lines to display (0 -7, 0-14)               }
  295. {                                                                          }
  296. { ======================================================================== }
  297. Procedure Set_Cursor (n: byte);
  298. Type
  299.    regrec = Record
  300.               ax,bx,cx,dx,bp,si,di,ds,es,flags: integer
  301.             End;
  302. Var regpak      : regrec;
  303.     top, bottom : byte;
  304. Begin
  305.    If Mem[$0040:$0049] = 7 Then bottom := 13
  306.    Else bottom := 7;
  307.    regpak.ax:= $100;
  308.    If n <= bottom Then top := bottom - n + 1
  309.    Else top := 0;
  310.    regpak.cx := top shl 8 or bottom;
  311.    Intr($10,regpak)
  312. End;
  313.  
  314. { ===================================================================== }
  315. { INITWINDO - Initialize the window variables                           }
  316. {                                                                       }
  317. { Use this routine before using MAKEWINDO, REMOVEWINDO or TITLEWINDO    }
  318. {                                                                       }
  319. {    Inputs:                                                            }
  320. {       txtcolor  : byte;    Starting text color                        }
  321. {       bkgndclr  : byte;    Starting background color                  }
  322. { ===================================================================== }
  323. Procedure InitWindo(txtcolor,bkgndclr : byte);
  324. Begin
  325.    brd[5].ul  := chr(08);   { Set up circle border constants    }
  326.    brd[5].ur  := chr(08);
  327.    brd[5].ll  := chr(08);
  328.    brd[5].lr  := chr(08);
  329.    brd[5].hz  := chr(08);
  330.    brd[5].vtl := chr(08);
  331.    brd[5].vtr := chr(08);
  332.    brd[6].ul  := chr(10);   { Set up diamond border constants   }
  333.    brd[6].ur  := chr(10);
  334.    brd[6].ll  := chr(10);
  335.    brd[6].lr  := chr(10);
  336.    brd[6].hz  := chr(10);
  337.    brd[6].vtl := chr(10);
  338.    brd[6].vtr := chr(10);
  339.    textcolor(txtcolor);
  340.    textbackground(bkgndclr);
  341.    wndo[0].rowb   := 0;       { Initialize non-window zero }
  342.    wndo[0].rowe   := 24;
  343.    wndo[0].colb   := 0;
  344.    wndo[0].cole   := 79;
  345.    wndo[0].attrib := (bkgndclr * 16) + txtcolor;
  346.    wndo[0].bordr  := noneb;
  347.    wndo[0].lastx  := Wherex;
  348.    wndo[0].lasty  := Wherey;
  349.    l_i := 0;
  350. End;
  351.  
  352. { ===================================================================== }
  353. { MAKEWINDO - Create a window                                           }
  354. {                                                                       }
  355. {    Inputs:                                                            }
  356. {         colb     : byte;   Start column     (1 - 80)                  }
  357. {         rowb     : byte;   Start row        (1 - 25)                  }
  358. {         cole     : byte;   End column       (1 - 80)                  }
  359. {         rowe     : byte;   End row          (1 - 25)                  }
  360. {         tcolor   : byte;   Text color       (0 - 15)                  }
  361. {         tback    : byte;   Text background  (0 - 7, > 7 for blinking) }
  362. {         bordr    : boolean;   Border indicator (0 - 9)                }
  363. { ===================================================================== }
  364. Procedure MakeWindo(colb,rowb,cole,rowe,tcolor,tback:byte;bordr:byte);
  365. Var i     : byte;
  366.     wsize : integer;
  367.     pseg  : integer;
  368.     pofs  : integer;
  369.     mema  : real;
  370. Begin
  371.    rowb := rowb - 1;  { Set coordinates relative to zero }
  372.    rowe := rowe - 1;
  373.    colb := colb - 1;
  374.    cole := cole - 1;
  375.    Normalize(rowb,rowe);
  376.    Normalize(colb,cole);
  377.    wsize := 2 * ((cole - colb + 1) * (rowe - rowb + 1));  { Total size of area }
  378.                                                      { needed to store display }
  379.    If l_i + 1 > maxwin Then
  380.    Begin
  381.       Writeln('Too many Windows!');
  382.       Bleep(4);
  383.    End
  384.    Else
  385.    Begin
  386.       If memavail < 0 then mema := 65536.0 + memavail
  387.       else mema := memavail;
  388.       If (wsize DIV 16 + 1) > mema Then
  389.       Begin
  390.          Writeln('Not enough Heap space!');
  391.          Bleep(4);
  392.       End
  393.       Else
  394.       Begin
  395.          wndo[l_i].lastx  := Wherex;   { Store old cursor coordinates }
  396.          wndo[l_i].lasty  := Wherey;
  397.          l_i := l_i + 1;        { Go to next window level }
  398.          Textcolor(tcolor);
  399.          Textbackground(tback);
  400.          wndo[l_i].rowb := rowb;   { Store all variables for this window }
  401.          wndo[l_i].rowe := rowe;
  402.          wndo[l_i].colb := colb;
  403.          wndo[l_i].cole := cole;
  404.          wndo[l_i].attrib := (tback * 16) + tcolor;
  405.          wndo[l_i].bordr  := bordr;
  406.          GetMem(wndoptr[l_i],wsize);   { Get enough heap to store old display }
  407.          tmpptr := wndoptr[l_i];
  408.          For i := rowb To rowe Do  { Store old display one row at a time }
  409.          Begin
  410.             GetDisp(colb,i,(cole-colb+1),tmpptr);
  411.             pseg   := Seg(tmpptr^);
  412.             pofs   := Ofs(tmpptr^);
  413.             pofs   := pofs + 2 * (cole - colb + 1);
  414.             tmpptr := Ptr(pseg,pofs);
  415.          End;
  416.          wndostr[0] := chr(cole - colb + 1);  { Set up String length }
  417.          If bordr = noneb Then
  418.          Begin
  419.             FillChar(wndostr[1],cole-colb+1,' '); { Do no border }
  420.             For i := rowb To rowe Do DispLine(colb,i,wndo[l_i].attrib,wndostr);
  421.             Window(colb+1,rowb+1,cole+1,rowe+1); { Create actual Turbo window }
  422.          End
  423.          Else
  424.          Begin
  425.             wndostr[1] := brd[bordr].ul;      { Do border top line }
  426.             wndostr[cole-colb+1] := brd[bordr].ur;
  427.             FillChar(wndostr[2],cole-colb-1,brd[bordr].hz);
  428.             DispLine(colb,rowb,wndo[l_i].attrib,wndostr);
  429.             wndostr[1] := brd[bordr].vtl;     { Do border middle lines }
  430.             wndostr[cole-colb+1] := brd[bordr].vtr;
  431.             FillChar(wndostr[2],cole-colb-1,' ');
  432.             For i := rowb+1 To rowe-1 Do DispLine(colb,i,wndo[l_i].attrib,wndostr);
  433.             wndostr[1] := brd[bordr].ll;      { Do border bottom line }
  434.             wndostr[cole-colb+1] := brd[bordr].lr;
  435.             FillChar(wndostr[2],cole-colb-1,brd[bordr].hz);
  436.             DispLine(colb,rowe,wndo[l_i].attrib,wndostr);
  437.             Window(colb+2,rowb+2,cole,rowe);  { Create actual Turbo window }
  438.          End;
  439.          Gotoxy(1,1);
  440.       End;
  441.    End;
  442. End;
  443.  
  444. { ===================================================================== }
  445. { REMOVEWINDO - Remove the last window created from the screen.  To     }
  446. {               get back to the original screen, there must be as many  }
  447. {               Removewindos as there are Makewindos.                   }
  448. {                                                                       }
  449. {    Inputs:                                                            }
  450. {         None                                                          }
  451. { ===================================================================== }
  452. Procedure RemoveWindo;
  453. Var i    : byte;
  454.     wsize: integer;
  455.     pseg : integer;
  456.     pofs : integer;
  457. Begin
  458.    If l_i = 0 Then
  459.    Begin
  460.       Writeln('No Window To Remove!');
  461.       Bleep(4);
  462.    End
  463.    Else
  464.    Begin
  465.       wsize  := wndo[l_i].cole - wndo[l_i].colb + 1;
  466.       tmpptr := wndoptr[l_i];
  467.       For i  := wndo[l_i].rowb To wndo[l_i].rowe Do   { Put back old display }
  468.       Begin
  469.          DispAll(wndo[l_i].colb,i,wsize,tmpptr);
  470.          pseg   := Seg(tmpptr^);
  471.          pofs   := Ofs(tmpptr^);
  472.          pofs   := pofs + 2 * wsize;
  473.          tmpptr := Ptr(pseg,pofs);
  474.       End;
  475.       wsize := 2 * ((wndo[l_i].cole - wndo[l_i].colb + 1) * (wndo[l_i].rowe - wndo[l_i].rowb + 1));
  476.       FreeMem(wndoptr[l_i],wsize);      { Release heap space }
  477.       l_i := l_i - 1;                   { Go to next lower level }
  478.       Textcolor(wndo[l_i].attrib AND $0F); { Set up all for this level }
  479.       Textbackground(wndo[l_i].attrib DIV 16);
  480.       If wndo[l_i].bordr = noneb Then
  481.          Window(wndo[l_i].colb+1,wndo[l_i].rowb+1,wndo[l_i].cole+1,wndo[l_i].rowe+1)
  482.       Else
  483.          Window(wndo[l_i].colb+2,wndo[l_i].rowb+2,wndo[l_i].cole,wndo[l_i].rowe);
  484.       Gotoxy(wndo[l_i].lastx,wndo[l_i].lasty);
  485.    End;
  486. End;
  487.  
  488. { ===================================================================== }
  489. { TITLEWINDO - Place a centered title in the top border of a window.    }
  490. {                                                                       }
  491. {    Inputs:                                                            }
  492. {         title  : string[80]; The title of the window                  }
  493. { ===================================================================== }
  494. Procedure TitleWindo (title: winstr);
  495. Var i : byte;
  496. Begin
  497.    i := (((wndo[l_i].cole-wndo[l_i].colb) - length(title)) DIV 2 + 1) + wndo[l_i].colb;
  498.    DispLine(i,wndo[l_i].rowb,wndo[l_i].attrib,title);
  499. End;
  500.